/*
 * @Author: 你的名字
 * @Date: 2022-10-09 15:56:47
 * @FilePath: /demo-gather/src/lib/http.js
 * @Description: 
 */
import axios from "axios";
import nprogress from "nprogress";
import "nprogress/nprogress.css";
import qs from "qs";
import { Message, MessageBox } from "element-ui";
import { isNil, assign } from "lodash";

import { router } from "@/router";
import localstorage from "@/lib/localstorage";
import { translateUrlParams, patchUrlParams, saveLocalStorageData } from "@/lib/utils";
import { httpStatus } from "@/common/constants/errorCode";
import { refreshToken } from "@/api/login/login.service";

// 请求超时时间10s
const requestTimeOut = 60 * 1000;

// 更换令牌的时间区间5min
const replaceTokenTime = 5 * 60 * 1000;

// 提示信息显示时长5s
const messageAliveDuration = 5 * 1000;

// 设置请求超时时间
axios.defaults.timeout = requestTimeOut;

// 返回状态码
axios.defaults.validateStatus = status => {
  return status >= 200 && status <= 500;
};

// nprogress配置
nprogress.configure({
  showSpinner: false
});

// 创建全局请求实例对象
const service = axios.create({
  // baseURL: "http://192.168.10.214:8301"
}
);

// 创建token刷新后的全局请求实例对象
const newService = axios.create();

const getLoginUrl = () => {
  // if (window.location.href.includes("/analyze")) {
  //   return "/analyze/login";
  // } else if (window.location.href.includes("/management")) {
  //   return "/management/login";
  // } else if (window.location.href.includes("/operation")) {
  //   return "/operation/login";
  // }
  return "/login";
};

// 全局请求实例对象添加请求拦截器
service.interceptors.request.use(
  config => {
    // 进度条为0
    nprogress.start();

    // 不同model的处理方法
    if (!!config.model && config.model === "patchUrl" && Object.keys(config.params).length !== 0) {
      const { url, params } = patchUrlParams(config.url, config.params);
      config.url = url;
      config.params = params;
    }

    // 处理get请求
    if (config.method === "get" || config.method === "delete") {
      config.paramsSerializer = params => {
        return qs.stringify(params, { arrayFormat: "comma" });
      };
    }

    try {
      // 获取当前到期时间
      const expireTime = localstorage.get("EXPIRE_TIME", 0);

      if (!expireTime) {
        return config;
      }

      // 当前时间戳
      const currentTime = new Date().getTime();

      // 当前token
      const token = localstorage.get("ACCESS_TOKEN", "");

      // 刷新后的token
      const refreshTokenTag = localstorage.get("REFRESH_TOKEN", "");

      // 剩余毫秒数
      const restTime = expireTime - currentTime;

      // 是否是外部请求
      const external = config.url.includes("areas_v3") || config.url.includes("apache/echarts-website");

      // token是否未失效
      if (restTime >= replaceTokenTime && token && !external) {
        config.headers["Authorization"] = `Bearer ${token}`;
      }

      if (config.headers.isLogin && restTime < replaceTokenTime) {
        // 刷新token
        setRefreshToken(config, refreshTokenTag);
      }
    } catch (e) {
      console.error(e);
    }

    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 添加响应拦截器
service.interceptors.response.use(
  response => {
    // 进度条为100%
    nprogress.done();

    const status = Number(response.status) || 200;
    const message = response.data.message || httpStatus[status.toString()] || httpStatus["default"];

    // 认证失效无权限
    if (status === 401 && JSON.parse(localStorage.getItem("onceCheck"))) {
      const options = {
        confirmButtonText: "确定",
        showClose: false,
        callback: () => {
          router.push(getLoginUrl());
        }
      };
      // 提示框
      MessageBox.alert("登录已过期，请重新登录", "温馨提示", options);
      localStorage.setItem("onceCheck", false);
      return Promise.reject(new Error(message));
    }

    // 刷新token无效 待补充

    // 处理请求未成功
    if (status !== 200) {
      // 弹框报错
      const options = {
        message,
        type: "error",
        duration: messageAliveDuration
      };
      if (JSON.parse(localStorage.getItem("onceCheck"))) Message(options);
      return Promise.reject(new Error(message));
    }

    // 获取原始response数据
    if (response.config.headers["isGetRowData"]) {
      return response;
    } else {
      // 统一处理返回data中的code，message
      const dataCode = response.data.code || 0;
      const dataMessage = response.data.message || "";
      if (dataCode !== 0) {
        // 不为0均为异常
        // 弹框报错
        const options = {
          message: dataMessage,
          type: "error",
          duration: messageAliveDuration
        };
        Message(options);
        return Promise.reject(new Error(dataMessage));
      }
      return response.data;
    }
  },
  error => {
    nprogress.done();
    return Promise.reject(error);
  }
);

// 封装请求方法
const http = {
  // 请求通用方法
  request(configOptions) {
    return service.request(configOptions);
  },
  // 刷新token
  refresh(url, params, options = {}) {
    // 新增属性
    params["grant_type"] = "refresh_token";
    // 配置
    const configOptions = {
      // transformRequest: [
      //   params => {
      //     return translateUrlParams(params);
      //   }
      // ],
      headers: {
        Authorization: "Basic Y21pY3Q6MTIzNDU2" //请求头信息
      }
    };

    assign(configOptions, options || {});

    return newService.post(url, params, configOptions);
  },
  // 登录
  login(url, params, options = {}) {
    // 新增属性
    params["grant_type"] = "password";
    // 配置
    const configOptions = {
      transformRequest: [
        params => {
          return translateUrlParams(params);
        }
      ],
      headers: {
        Authorization: "Basic Y21pY3Q6MTIzNDU2", //请求头信息
        isLogin: true
      }
    };

    assign(configOptions, options || {});
    console.log(configOptions, options, params, '>>>>>>>>>>>>')
    return service.post(url, params, configOptions);
  },
  // get方法
  get(url, params = {}, options = {}) {
    if (!isNil(params)) {
      const configOptions = assign({ params }, options || {});
      return service.get(url, configOptions);
    }
    return service.get(url);
  },
  // post方法
  post(url, data, options = {}) {
    const configOptions = {
      // transformRequest: [
      //   data => {
      //     return translateUrlParams(data);
      //   }
      // ],
      headers: {
        // "Content-Type": "application/x-www-form-urlencoded"
        "Content-Type": "application/json"
      }
    };

    assign(configOptions, options || {});

    return service.post(url, data, configOptions);
  },
  // put方法
  put(url, data, options = {}) {
    const configOptions = {
      // transformRequest: [
      //   data => {
      //     return translateUrlParams(data);
      //   }
      // ],
      headers: {
        "Content-Type": "application/json"
      }
    };

    assign(configOptions, options || {});

    return service.put(url, data, configOptions);
  },
  // delete方法
  delete(url, params = {}, options = {}) {
    if (!isNil(params)) {
      const configOptions = assign({ params }, options || {});
      return service.delete(url, configOptions);
    }
    return service.delete(url);
  },
  // download方法 待补充
  download(url, params, configs) {
    return service({
      method: "get",
      url: url,
      headers: configs.headers || {},
      data: params,
      responseType: "blob"
    });
  },
  // upload方法
  upload(url, params, options = {}) {
    const configOptions = {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    };

    assign(configOptions, options || {});

    return service.post(url, params, configOptions);
  }
};

// 配置刷新后的token
function setRefreshToken(config, token) {
  refreshToken(token).then(response => {
    if (response.status === 200) {
      // 刷新localstorage数据
      saveLocalStorageData(response.data);
      // 刷新header的token
      const newToken = localstorage.get("ACCESS_TOKEN");
      config.headers["Authorization"] = `Bearer ${newToken}`;
      localStorage.setItem("onceCheck", true);
    }
  });
}

export default http;
